package cn.com.dmg.myspringboot.quartz;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

/**
 * @ClassName TestScheduler
 * @Description 参考代码 https://www.jb51.net/program/307861tgu.htm
 * @author zhum
 * @date 2024/8/21 17:12
 */
public class TestScheduler {

    public static Scheduler scheduler = getScheduler();

    public static String SCHEDULER_OPR_START = "start";
    public static String SCHEDULER_OPR_PAUSE = "pause";
    public static String SCHEDULER_OPR_RESUME = "resume";
    public static String SCHEDULER_OPR_REMOVE = "remove";

    public static Scheduler getScheduler() {
        try {
            return StdSchedulerFactory.getDefaultScheduler();
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws Exception {
        String taskCode1 = "123";
        String taskCode2 = "456";
        String jobGroup = "testGroup";
        startJob(taskCode1, "", "0/1 * * * * ? ", jobGroup, "cn.com.dmg.myspringboot.quartz.TestJob");
        //十秒钟之后新增任务2
        Thread.sleep(10000);
        startJob(taskCode2, "", "0/1 * * * * ? ", jobGroup, "cn.com.dmg.myspringboot.quartz.TestJob");

        //10秒钟之后删除任务1
        Thread.sleep(10000);
        deleteJob(taskCode1, jobGroup);

        //10秒钟之后修改任务2的执行时间为2秒一次
        modifyJob(taskCode2, jobGroup, "0/2 * * * * ? ");


        //testJob();
    }

    public static void testJob() throws Exception {
        // 获取任务调度的实例
        // 定义任务调度实例, 并与TestJob绑定
        JobDetail job = JobBuilder.newJob(TestJob.class)
                .withIdentity("testJob", "testJobGroup")
                .build();
        // 定义触发器, 会马上执行一次, 接着5秒执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("testTrigger", "testTriggerGroup")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
                .build();
        // 使用触发器调度任务的执行
        scheduler.scheduleJob(job, trigger);
        // 开启任务
        scheduler.start();
    }



    /**
     * 启动任务
     */
    public static void startJob(String taskCode, String taskName, String cron, String jobGroup,
                         String className) throws Exception{
        Class<Job> jobClass = null;
        try {
            jobClass = (Class<Job>) Class.forName(className);//获取任务执行类
        } catch (ClassNotFoundException e) {
            throw new Exception("任务类不存在");
        }
        //创建job，指定job名称和分组
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(taskCode, jobGroup).build();
        //创建表达式工作计划
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        //创建触发器
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(taskCode, jobGroup)
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
        // 开启任务
        scheduler.start();
    }

    /**
     * 修改定时任务执行时间
     * @param taskCode
     * @param jobGroup
     * @param cron 新的时间
     * @throws Exception
     */
    public static void modifyJob(String taskCode, String jobGroup, String cron) throws Exception{
        TriggerKey triggerKey = new TriggerKey(taskCode, jobGroup);
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        String oldCron = trigger.getCronExpression();
        if(!oldCron.equals(cron)){
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(taskCode, jobGroup)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
            Date date = scheduler.rescheduleJob(triggerKey, cronTrigger);
            if(date == null){
                throw new Exception("修改定时任务执行时间报错");
            }
        }
    }

    /**
     * 暂停某个定时任务（任务恢复后，暂停时间段内未执行的任务会继续执行，如暂停时间段内有2次，则会执行2次）
     * @param taskCode
     * @param jobGroup
     * @throws Exception
     */
    public void pauseJob(String taskCode, String jobGroup) throws Exception{
        JobKey jobKey = new JobKey(taskCode, jobGroup);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail == null){
            return;
        }
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复某个定时任务
     * @param taskCode
     * @param jobGroup
     * @throws Exception
     */
    public void resumeJob(String taskCode, String jobGroup) throws Exception{
        JobKey jobKey = new JobKey(taskCode, jobGroup);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail == null){
            return;
        }
        scheduler.resumeJob(jobKey);
    }

    /**
     * 删除某个定时任务
     * @param taskCode
     * @param jobGroup
     * @throws Exception
     */
    public static void deleteJob(String taskCode, String jobGroup) throws Exception{
        JobKey jobKey = new JobKey(taskCode, jobGroup);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail == null){
            return;
        }
        scheduler.deleteJob(jobKey);
    }
}
